home *** CD-ROM | disk | FTP | other *** search
/ IRIX 6.3 Development Libraries / SGI IRIX 6.3 Development Libraries.iso / dist6.3 / gl_dev.idb / usr / share / src / OpenGL / teach / motif / animate.c.z / animate.c
Encoding:
C/C++ Source or Header  |  1996-12-06  |  6.1 KB  |  233 lines

  1. /*
  2.  * animate.c - double buffered RGBA motif program with a work proc for animation
  3.  */
  4. /* compile: cc -o animate animate.c -lGLw -lGLU -lGL -lXm -lXt -lX11 */
  5. #include <stdlib.h>
  6. #include <stdio.h>
  7. #include <Xm/Frame.h>
  8. #include <Xm/RowColumn.h>
  9. #include <X11/GLw/GLwMDrawA.h>
  10. #include <X11/keysym.h>
  11. #include <X11/Xutil.h>
  12. #include <GL/glx.h>
  13. #include <GL/glu.h>
  14.  
  15. static void draw_scene(Widget w);
  16. static void initialize(void);
  17. static Boolean redraw_proc(XtPointer clientData);
  18.  
  19. static int attribs[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_DOUBLEBUFFER, None};
  20.  
  21. static String fallbackResources[] = {
  22.     "*sgiMode: True",
  23.     "*useSchemes: all",
  24.     "*glxwidget.width: 300", "*glxwidget.height: 300",
  25.     "*frame.shadowType: SHADOW_IN",
  26.     NULL};
  27.  
  28. static struct {            /* global UI variables - keep them together */
  29.     XtAppContext appctx;
  30.     Widget glxwidget;
  31.     Boolean direct;
  32.     XtWorkProcId animate_wpid;
  33. } state;
  34.  
  35. static void
  36. input(Widget w, XtPointer client_data, XtPointer call) {
  37.     char buf[31];
  38.     KeySym keysym;
  39.     XEvent *event = ((GLwDrawingAreaCallbackStruct *) call)->event;
  40.  
  41.     switch(event->type) {
  42.     case KeyRelease:
  43.     XLookupString(&event->xkey, buf, sizeof buf, &keysym, NULL);
  44.     switch(keysym) {
  45.     case XK_Escape:
  46.         exit(EXIT_SUCCESS);
  47.         break;
  48.     default: break;
  49.     }
  50.     break;
  51.     }
  52. }
  53.  
  54. static void
  55. resize(Widget w, XtPointer client_data, XtPointer call) {
  56.     GLwDrawingAreaCallbackStruct *call_data;
  57.     call_data = (GLwDrawingAreaCallbackStruct *) call;
  58.  
  59.     glViewport(0, 0, call_data->width, call_data->height);
  60. }
  61.  
  62. static void
  63. expose(Widget w, XtPointer client_data, XtPointer call) {
  64.     GLwDrawingAreaCallbackStruct *call_data;
  65.     call_data = (GLwDrawingAreaCallbackStruct *) call;
  66.  
  67.     draw_scene(w);
  68. }
  69.  
  70. static void
  71. menu(Widget w, XtPointer clientData, XtPointer callData) {
  72.     int entry = (int) clientData;
  73.  
  74.     switch (entry) {
  75.     case 0:
  76.     if (state.animate_wpid) {
  77.         XtRemoveWorkProc(state.animate_wpid);
  78.         state.animate_wpid = 0;
  79.     } else {
  80.         /* register work proc */
  81.         state.animate_wpid = XtAppAddWorkProc(state.appctx, redraw_proc, &state.glxwidget);
  82.     }
  83.     break;
  84.     case 1:
  85.     exit(EXIT_SUCCESS);
  86.     break;
  87.     default:
  88.     break;
  89.     }
  90. }
  91.  
  92. static void
  93. activate_menu(Widget w, XtPointer clientData, XEvent *event, Boolean *cont) {
  94.     Widget popup = *((Widget *) clientData);
  95.  
  96.     if (event->type == ButtonPress && event->xbutton.button == Button3) {
  97.     XmMenuPosition(popup, &event->xbutton);
  98.     XtManageChild(popup);
  99.     }
  100. }
  101.  
  102. static void
  103. create_popup(Widget parent) {
  104.     Arg args[10];
  105.     static Widget popup;
  106.     int n;
  107.     XmButtonType button_types[] = {
  108.     XmPUSHBUTTON, XmSEPARATOR, XmPUSHBUTTON,
  109.     };
  110.     XmString button_labels[XtNumber(button_types)];
  111.  
  112.     button_labels[0] = XmStringCreateLocalized("animate");
  113.     button_labels[1] = NULL;
  114.     button_labels[2] = XmStringCreateLocalized("quit");
  115.  
  116.     n = 0;
  117.     XtSetArg(args[n], XmNbuttonCount, XtNumber(button_types)); n++;
  118.     XtSetArg(args[n], XmNbuttonType, button_types); n++;
  119.     XtSetArg(args[n], XmNbuttons, button_labels); n++;
  120.     XtSetArg(args[n], XmNsimpleCallback, menu); n++;
  121.     popup = XmCreateSimplePopupMenu(parent, "popup", args, n);
  122.     XtAddEventHandler(parent, ButtonPressMask, False, activate_menu, &popup);
  123.  
  124.     XmStringFree(button_labels[0]);
  125.     XmStringFree(button_labels[2]);
  126. }
  127.  
  128. static void
  129. map_change(Widget w, XtPointer clientData, XEvent *event, Boolean *cont) {
  130.     switch (event->type) {
  131.     case MapNotify:
  132.     /* resume animation if we become mapped and are in the animated state */
  133.         if (state.animate_wpid != 0)
  134.          state.animate_wpid = XtAppAddWorkProc(state.appctx, redraw_proc, &state.glxwidget);
  135.         break;
  136.     case UnmapNotify:
  137.     /* don't animate if we aren't mapped */
  138.         if (state.animate_wpid) XtRemoveWorkProc(state.animate_wpid);
  139.         break;
  140.     }
  141. }
  142.  
  143. main(int argc, char *argv[]) {
  144.     Display        *dpy;
  145.     XVisualInfo    *visinfo;
  146.     GLXContext      glxcontext;
  147.     Widget          toplevel, frame;
  148.  
  149.     toplevel = XtOpenApplication(&state.appctx, "animate", NULL, 0, &argc, argv,
  150.         fallbackResources, applicationShellWidgetClass, NULL, 0);
  151.     dpy = XtDisplay(toplevel);
  152.  
  153.     frame = XmCreateFrame(toplevel, "frame", NULL, 0);
  154.     XtManageChild(frame);
  155.  
  156.     /* specify visual directly */
  157.     if (!(visinfo = glXChooseVisual(dpy, DefaultScreen(dpy), attribs)))
  158.     XtAppError(state.appctx, "no suitable RGB visual");
  159.  
  160.     state.glxwidget = XtVaCreateManagedWidget("glxwidget", glwMDrawingAreaWidgetClass,
  161.     frame, GLwNvisualInfo, visinfo, NULL);
  162.     XtAddCallback(state.glxwidget, GLwNexposeCallback, expose, NULL);
  163.     XtAddCallback(state.glxwidget, GLwNresizeCallback, resize, NULL);
  164.     XtAddCallback(state.glxwidget, GLwNinputCallback, input, NULL);
  165.  
  166.     create_popup(frame);
  167.  
  168.     XtAddEventHandler(toplevel, StructureNotifyMask, False, map_change, NULL);
  169.     XtRealizeWidget(toplevel);
  170.  
  171.     glxcontext = glXCreateContext(dpy, visinfo, 0, GL_TRUE);
  172.     state.direct = glXIsDirect(dpy, glxcontext);
  173.     GLwDrawingAreaMakeCurrent(state.glxwidget, glxcontext);
  174.  
  175.     initialize();
  176.  
  177.     XtAppMainLoop(state.appctx);
  178. }
  179.  
  180. static void
  181. initialize(void) {
  182.     glShadeModel(GL_FLAT);
  183.     gluPerspective(40., 3.0/2.0, 0.001, 100000.0);
  184.     glTranslatef(0.0, 0.0, -3.0);
  185.     glClearColor(0.2,0.2,0.2,0.);
  186. }
  187.  
  188. static void
  189. side(void) { /* make a square translated 0.5 in the z direction */
  190.     glPushMatrix();
  191.     glTranslatef(0.0,0.0,0.5);
  192.     glRectf(-0.5,-0.5,0.5,0.5);
  193.     glPopMatrix();
  194. }
  195.  
  196. static void
  197. cube(void) { /* make a cube out of 4 squares */
  198.     glPushMatrix();
  199.     side();
  200.     glRotatef(90.,1.,0.,0.);
  201.     side();
  202.     glRotatef(90.,1.,0.,0.);
  203.     side();
  204.     glRotatef(90.,1.,0.,0.);
  205.     side();
  206.     glPopMatrix();
  207. }
  208.  
  209. static void
  210. draw_scene(Widget w) {
  211.     static float rot = 0.;
  212.  
  213.     glClear(GL_COLOR_BUFFER_BIT);
  214.     glColor3f(.1, .1, .8);
  215.     glPushMatrix();
  216.     if ((rot += 5.) > 360.) rot -= 360.;
  217.     glRotatef(rot,0.,1.,0.);
  218.     cube();
  219.     glScalef(0.3,0.3,0.3);
  220.     glColor3f(.8, .8, .1);
  221.     cube();
  222.     glPopMatrix();
  223.     GLwDrawingAreaSwapBuffers(w);
  224.     if (!state.direct) glFinish();    /* hack to improve net interactivity */
  225. }
  226.  
  227. static Boolean
  228. redraw_proc(XtPointer clientData) {
  229.     Widget *w = (Widget *)clientData;
  230.     draw_scene(*w);
  231.     return False;
  232. }
  233.